package cn.sc.summer.core.interceptor;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.extra.spring.SpringUtil;
import cn.sc.summer.constant.model.Result;
import cn.sc.summer.constant.util.ConvertUtil;
import cn.sc.summer.exception.hodler.SpringContextHolder;
import cn.sc.summer.token.service.EncryptService;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.lang.NonNull;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import javax.servlet.http.HttpServletRequest;

/**
 * 类名：返回数据进行解密
 *
 * @author a-xin
 * @date 2024/5/13 10:48
 */
@Slf4j
@ControllerAdvice
public class ResponseInterceptor implements ResponseBodyAdvice<Object> {

    @Override
    public boolean supports(@NonNull MethodParameter methodParameter,
                            @NonNull Class aClass) {
        return true;
    }

    @Override
    public Object beforeBodyWrite(Object body,
                                  @NonNull MethodParameter methodParameter,
                                  @NonNull MediaType mediaType,
                                  @NonNull Class aClass,
                                  @NonNull ServerHttpRequest serverHttpRequest,
                                  @NonNull ServerHttpResponse serverHttpResponse) {

        HttpServletRequest request = SpringContextHolder.getHttpServletRequest();
        EncryptService encryptService = SpringUtil.getBean(EncryptService.class);

        if (!encryptService.checkEncrypt(request)) {
            return body;
        }
        if (ObjectUtil.isNotNull(body)) {
            String encrypt = encryptService.encrypt(request, ConvertUtil.toJsonString(body));
            try {
                return JSONObject.parseObject(encrypt, Result.class);
            } catch (Exception exception) {
                return encrypt;
            }
        }

        return body;
    }

}
